package cc.mrbird.febs.pay.wx;

import cc.mrbird.febs.common.utils.OrderNoUtil;
import cc.mrbird.febs.pay.base.AbstractPayStrategy;
import cc.mrbird.febs.pay.base.PayModelFactory;
import cc.mrbird.febs.pay.enums.PayType;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Classname WeChatPayAppPay
 * @Description TODO
 * @Author 沐沐
 * @Date 2021/10/6 15:12
 * @Version 1.0.0
 */
@Slf4j
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class WeChatPayNativePay extends AbstractPayStrategy {

//    @Resource
    private CloseableHttpClient wxPayClient;

    /**
     * 支付
     *
     * @param parameterMap@return
     * @throws
     */
    @Override
    public Object pay(Map<String, String> parameterMap) throws Exception {
        //请求URL
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
        String orderSn = OrderNoUtil.getOrderNum(Long.valueOf(32326));
        Gson gson = new Gson();
        Map map = new ConcurrentHashMap();
        map.put("appid", "");
        map.put("mchid", "");
        map.put("description", "");
        map.put("out_trade_no", orderSn);
        map.put("notify_url", "");
        Map amountMap = new ConcurrentHashMap();
        amountMap.put("total", "4000");
        amountMap.put("currency", "CNY");
        map.put("amount", amountMap);

        Map payerMap = new ConcurrentHashMap();
        payerMap.put("openid", "1c745c0b5e7d4a51aca691fb2acc4a8b");
        map.put("payer", payerMap);
        // 请求body参数
        String jsonParam = gson.toJson(map);
        log.info("统一下单参数：{}", jsonParam);
        StringEntity entity = new StringEntity(jsonParam, "utf-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);
        httpPost.setHeader("Accept", "application/json");

        //完成签名并执行请求
        CloseableHttpResponse response = wxPayClient.execute(httpPost);
        try {
            int statusCode = response.getStatusLine().getStatusCode();
            String bodyAsString = EntityUtils.toString(response.getEntity());
            if (statusCode == 200) {
                log.info("统一下单 返回成功，响应参数：{}", bodyAsString);
            } else if (statusCode == 204) {
                log.info("统一下单 返回成功，响应应参数。");
            } else {
                log.error("统一下单 返回失败：{}。{}", statusCode, bodyAsString);
                throw new IOException("request failed");
            }
            ConcurrentHashMap<String, String> concurrentHashMap = gson.fromJson(bodyAsString, ConcurrentHashMap.class);
            String codeUrl = concurrentHashMap.get("code_url");

            Map resultMap = new ConcurrentHashMap();
            resultMap.put("codeUrl", codeUrl);
            resultMap.put("orderSn", orderSn);
            return resultMap;
        } finally {
            response.close();
            wxPayClient.close();
        }
    }

    @Override
    public Object cancel(Map<String, String> parameterMap) throws Exception {
        return null;
    }

    /**
     * 根据订单查询支付记录
     *
     * @param parameterMap@return
     * @throws
     */
    @Override
    public Object queryPay(Map<String, String> parameterMap) throws RuntimeException {
        return null;
    }

    /**
     * 退款
     *
     * @param parameterMap
     * @return
     * @throws
     */
    @Override
    public Object refund(Map<String, String> parameterMap) throws RuntimeException {
        return null;
    }

    /**
     * 退款查询
     *
     * @param stringStringMap
     * @return
     * @throws
     */
    @Override
    public Object queryRefund(Map<String, String> stringStringMap) throws RuntimeException {
        return null;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        PayModelFactory.register(PayType.WX_PAY_APP.getCode(), this);
    }
}
